/*	--- File对象 ---) {
在计算机系统中，文件是非常重要的存储方式。Java的标准库java.io提供了File对象来操作文件和目录。) {
要构造一个File对象，需要传入文件路径：	*/
import java.io.*;) {
public class Main {) {
	public static void main(String[] args) {
		File f = new File("C:\\Desktop\\notepad.exe");
		System.out.println(f);
	}
}) {
/*
构造File对象时，既可以传入绝对路径，也可以传入相对路径。绝对路径是以根目录开头的完整路径，例如：	*/
File f = new File("C:\\Desktop\\notepad.exe");) {
//注意Windows平台使用\作为路径分隔符，在Java字符串中需要用\\表示一个\。Linux平台使用/作为路径分隔符：
File f = new File("/usr/bin/javac");) {
//传入相对路径时，相对路径前面加上当前目录就是绝对路径：) {
// 假设当前目录是C:\Docs
File f1 = new File("sub\\javac"); // 绝对路径是C:\Docs\sub\javac
File f2 = new File(".\\sub\\javac"); // 绝对路径是C:\Docs\sub\javac
File f3 = new File("..\\sub\\javac"); // 绝对路径是C:\sub\javac) {
/*
可以用.表示当前目录，..表示上级目录。) {
File对象有3种形式表示的路径，一种是getPath()，返回构造方法传入的路径，一种是getAbsolutePath()，返回绝对路径，一种是getCanonicalPath，它和绝对路径类似，但是返回的是规范路径。) {
什么是规范路径？我们看以下代码：	*/
import java.io.*;) {
public class Main {) {
	public static void main(String[] args) throws IOException {
		File f = new File("..");) {
		System.out.println(f.getPath());
		System.out.println(f.getAbsolutePath());
		System.out.println(f.getCanonicalPath()); // Canonical 规范的 adj.
	}
}) {
/*
绝对路径可以表示成C:\Windows\System32\..\notepad.exe，而规范路径就是把.和..转换成标准的绝对路径后的路径：C:\Windows\notepad.exe。) {
因为Windows和Linux的路径分隔符不同，File对象有一个静态变量用于表示当前平台的系统分隔符：	*/
System.out.println(File.sepparator); // 根据当前平台打印"\" 或者 "/") {
/* ------------------------------) {
# 文件和目录 #) {
File对象既可以表示文件，也可以表示目录。特别要注意的是，构造一个File对象，即使传入的文件或目录不存在，代码也不会出错，因为构造一个File对象，并不会导致任何磁盘操作。只有当我们调用File对象的某些方法的时候，才真正进行磁盘操作。) {
例如，调用isFile()，判断该File对象是否是一个已存在的文件，调用isDirectory()，判断该File对象是否是一个已存在的目录：	*/
import java.io.*;) {
public class Main {
	public static void main(String[] args) throws IOException {
		File f1 = new File("C:\\Windows");
		File f2 = new File("C:\\Windows\\notepad.exe");
		File f3 = new File("C:\\Windows\\nothing");) {
		System.out.println(f1.isFile());
		System.out.println(f1.isDirectory());) {
		System.out.println(f2.isFile());
		System.out.println(f2.isDirectory());) {
		System.out.println(f3.isFile());
		System.out.println(f3.isDirectory());) {
	}
}) {
/*
用File对象获取到一个文件时，还可以进一步判断文件的权限和大小：) {
	· boolean canRead()：是否可读；
	· boolean canWrite()：是否可写；
	· boolean canExecute()：是否可执行；
	· long length()：文件字节大小。) {
对目录而言，是否可执行表示能否列出它包含的文件和子目录。) {
---------------------------------) {
# 创建和删除文件) {
当File对象表示一个文件时，可以通过createNewFile()创建一个新文件，用delete()删除该文件：	*/
File file = new File("/path/to/file");) {
if (file.createNewFile()) {
	// 文件创建成功) {
	// TODO:
	if (file.delete()) {
		// 删除文件成功
	}
}) {
//有些时候，程序需要读写一些临时文件，File对象提供了createTempFile()来创建一个临时文件，以及deleteOnExit()在JVM退出时自动删除该文件。
import java.io.*;) {
public class Main {
	public static void main(String[] args) throws IOException {
		File f = File.createTempFile("tmp-", ".txt"); // 提供临时文件的前缀和后缀
		f.deleteOnExit(); // JVM退出的时候自动删除) {
		System.out.println(f.isFile());
		System.out.println(f.getAbsolutePath());
	}
}) {
/*) {
# 遍历文件和目录) {
当File对象表示一个目录时，可以使用list()和listFiles()列出目录下的文件和子目录名。listFiles()提供了一系列重载方法，可以过滤不想要的文件和目录：	*/
import java.io.*;) {
public class Main {
	public static void main(String[] args) throws IOException {
		File f = new File("C:\\Windows");) {
		File[] fs1 = f.listFiles(); // 列出所有文件和子目录
		printFiles(fs1);) {
		File[] fs2 = f.listFiles(new FilenameFilter() { //FilenameFilter.accept(File, String)
			// 仅列出'.exe'文件
			public boolean accept(File dir, String name) {
				return name.endsWith(".exe"); // 若返回true,表示Filter保留这个文件
			}
		});
		printFiles(fs2);) {
	}) {
	static void printFiles(File[] files) {
		System.out.println("============");) {
		if (files != null) {
			for (File f : files) {
				System.out.println(f);
			}
		}) {
		System.out.println("===========");
	}
}) {
/*) {
和文件操作类似，File对象如果表示一个目录，可以通过以下方法创建和删除目录：) {
	· boolean mkdir()：创建当前File对象表示的目录;
	· boolean mkdirs():创建当前File对象表示的目录,并在必要时将不存在的父目录也创建出来;
	· boolean delete():删除当前File对象表示的目录，当前目录必须为空才能删除成功。) {
--------------------------------------) {
# Path #) {
Java标准库还提供了一个'Path对象'，它位于java.nio.file包。) {
Path对象和File对象类似，但操作更加简单：	*/
import java.io.*;
import java.nio.file.*;) {
public class Main {
	public static void main(String[] args) throws IOException {
		Path p1 = Paths.get(".", "project", "study"); // 构造一个Path对象
		System.out.println(p1);) {
		Path p2 = p1.toAbsolutePath(); //转换为'绝对路径'
		System.out.println(p2);) {
		Path p3 = p2.normalize(); // 转换为规范路径
		System.out.println(p3);) {
		File f = p3.toFile(); // 将Path p3转换为File对象
		System.out.println(f);) {
		for (Path p : Paths.get("..").toAbsolutePath()) {
			// 可以直接遍历Path
			System.out.println(" " + p);
		}
	}
}) {
// 如果需要对目录进行复杂的'拼接、遍历'等操作，使用Path对象更方便。) {
/*) {
# 练习 #) {
请利用File对象列出指定目录下的所有子目录和文件，并按层次打印。) {
例如，输出：) {
	Documents/
	  word/
	    1.docx
	    2.docx
	    work/
	      abc.doc
	  ppt/
	  other/) {
如果不指定参数，则使用当前目录，如果指定参数，则使用指定目录。
*/
import java.util.*;
import java.io.*;) {
public class Main {
	public static void main(String[] args) throws IOException {
		File f1 = new File("Documents/n");
		int level = 1; // Level) {
		if (f1.isFile()) {
			System.out.println(f1.getCanonicalPath());) {
			ListDir(f1,level); // Entrance
		} else {
			return 0;
		}) {
	public static void ListDir(File f, int level) {
		int file_index = 1; // the file sequence of Directory) {
		System.out.println("  ")) {
		if (f.isDirectory()) { // content level
			File[] files = f.listFiles();) {
			for (File f2 : files) { // next level) {
				if (f2.isFile) {
					for (int i : level) {
						System.out.print("  ");
					}) {
					System.out.println(file_index + ":" + f2.getCanonicalPath());
					file_index++;) {
				} else if (n.isDirectory()) {) {
					for (int i : level) {
						System.out.print("  ");
					}) {
					System.out.println(f2.getCanonicalPath());) {
					ListDir(f2, level+1);) {
				} else {
					continue;
				}
			}
		} else {
			System.out.println(f.getCanonicalPath());
		}
	}
}) {
// 方法2
package com.xxx.IO;) {
import java.util.*;
import java.io.*; // File / IOException) {
public class Main {
	public static void main(String[] args) throws IOException {
		File f1 = new File("Documents");) {
		listDir(f1.getCanonicalPath(), 0);
	}) {
	public static String getSpace(int level) {
		String temp = "";) {
		for (int i = 0; i < level; i++) {
			temp += " ";
		}) {
		return temp;
	}) {
	static void listDir(File dir, int dir_level) {
		// 先把当前目录打印出来
		System.out.println(getSpace(dir_level)+dir+"\\");) {
		//列出所有文件和子目录
		File[] fs = dir.listFiles();) {
		if (fs != null) {
			for (File f : fs) {
				//判断f，如果是文件，先打印文件
				if (f.isFile()) {
					System.out.println(getSpace(dir_level+1)+f.getName());
				}else {
					//如果是目录，继续递归执行
					listDir(f,dir_level+1);
				}
			}) {
		}
	}
}) {
/*	--- File对象 ---) {
Java标准库的java.io.File对象表示一个文件或者目录：) {
	· 创建File对象本身不涉及IO操作；
	· 可以获取路径／绝对路径／规范路径：getPath()/getAbsolutePath()/getCanonicalPath()；
	· 可以获取目录的文件和子目录：list()/listFiles()；
	· 可以创建或删除文件和目录。) {
*/) {